package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcWatchConfMapper;
import com.csun.cmny.provider.device.watch.WatchMessageHandler;
import com.csun.cmny.provider.device.watch.entity.WatchConstant;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.domain.DmcWatchConf;
import com.csun.cmny.provider.model.dto.watch.*;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.enums.watch.WatchTimeZoneEnum;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.DmcDeviceService;
import com.csun.cmny.provider.service.DmcWatchConfigService;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-01-17 16:52
 * @Description: the class dmc watch config service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcWatchConfigServiceImpl extends BaseService<DmcWatchConf> implements DmcWatchConfigService {

    String deviceNo;

    @Resource
    private CmnyMessageSource cmnyMessageSource;

    @Resource
    private DmcWatchConfMapper watchConfDao;

    @Resource
    private DmcDeviceService dmcDeviceService;

    @Resource
    private WatchMessageHandler watchMessageHandler;

    /**
     * query dmc watch config by device id
     *
     * @param deviceId  device id
     *
     * @return  the dmc watch conf by device id
     */
    @Override
    public DmcWatchConf queryDmcWatchConfigByDeviceId(Long deviceId) {

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, deviceId);
        }

        // 2.判断设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf = watchConfDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcWatchConf)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610010, deviceId);
        }

        deviceNo = dmcDevice.getDeviceNo();

        return dmcWatchConf;
    }

    /**
     * set watch family number
     *
     * @param watchFamilyNumberDto  watch family number dto
     * @param loginAuthDto          login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchFamilyNumber(WatchFamilyNumberDto watchFamilyNumberDto,
                                        LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchFamilyNumberDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验电话号码 - 红键
        if (StringUtils.isNotEmpty(watchFamilyNumberDto.getRedKeyNumber())) {
            if (!PubUtils.isMobileNumber(watchFamilyNumberDto.getRedKeyNumber())) {
                throw new DmcBizException(ErrorCodeEnum.DMC100610005);
            }
        }
        dmcWatchConfUpt.setRedKeyNumber(watchFamilyNumberDto.getRedKeyNumber());

        // 3.校验电话号码 - 黄键
        if (StringUtils.isNotEmpty(watchFamilyNumberDto.getYellowKeyNumber())) {
            if (!PubUtils.isMobileNumber(watchFamilyNumberDto.getYellowKeyNumber())) {
                throw new DmcBizException(ErrorCodeEnum.DMC100610006);
            }
        }
        dmcWatchConfUpt.setYellowKeyNumber(watchFamilyNumberDto.getYellowKeyNumber());

        // 4.校验电话号码 - 绿键
        if (StringUtils.isNotEmpty(watchFamilyNumberDto.getGreenKeyNumber())) {
            if (!PubUtils.isMobileNumber(watchFamilyNumberDto.getGreenKeyNumber())) {
                throw new DmcBizException(ErrorCodeEnum.DMC100610007);
            }
        }
        dmcWatchConfUpt.setGreenKeyNumber(watchFamilyNumberDto.getGreenKeyNumber());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        // 5.更新亲情号码
        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环亲情号码
            StringBuilder sb = new StringBuilder("" + dmcWatchConfUpt.getRedKeyNumber());
            sb.append("&" + dmcWatchConfUpt.getYellowKeyNumber());
            sb.append("&" + dmcWatchConfUpt.getGreenKeyNumber());
            watchMessageHandler.setFamilyNumber(deviceNo, sb.toString());
        }

        return result;
    }

    /**
     * set watch heart upload rate
     *
     * @param watchHeartUploadRateDto   watch heart upload rate dto
     * @param loginAuthDto              login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchHeartUploadRate(WatchHeartUploadRateDto watchHeartUploadRateDto,
                                           LoginAuthDto loginAuthDto) {

        Long deviceId = watchHeartUploadRateDto.getDeviceId();
        Integer heartRate = watchHeartUploadRateDto.getHeartRate();

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(deviceId);
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验心率上传频率参数
        Preconditions.checkArgument(heartRate != null,
                cmnyMessageSource.getMessage("watch.config.heart.rate.null", null));

        Preconditions.checkArgument(heartRate >= 0
                        && heartRate <= 300,
                cmnyMessageSource.getMessage("watch.config.heart.rate.range", null));

        dmcWatchConfUpt.setHeartRate(heartRate);
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        // 3.更新心率
        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环心率上传频率
            watchMessageHandler.setHeartOrGpsRate(deviceNo,
                    WatchConstant.WATCH_CONF_RATE_TYPE_HEART, heartRate);
        }

        return result;
    }

    /**
     * set watch gps upload rate
     *
     * @param watchGpsUploadRateDto watch gps upload rate dto
     * @param loginAuthDto          login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchGpsUploadRate(WatchGpsUploadRateDto watchGpsUploadRateDto,
                                         LoginAuthDto loginAuthDto) {

        Long deviceId = watchGpsUploadRateDto.getDeviceId();
        Integer gpsRate = watchGpsUploadRateDto.getGpsRate();

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(deviceId);
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 3.校验gps上传频率参数
        Preconditions.checkArgument(gpsRate != null,
                cmnyMessageSource.getMessage("watch.config.gps.rate.null", null));

        Preconditions.checkArgument(gpsRate >= 0
                        && gpsRate <= 300,
                cmnyMessageSource.getMessage("watch.config.gps.rate.range", null));

        // 4.更新手环配置
        dmcWatchConfUpt.setGpsRate(watchGpsUploadRateDto.getGpsRate());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);
        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环gps上传频率
            watchMessageHandler.setHeartOrGpsRate(deviceNo,
                    WatchConstant.WATCH_CONF_RATE_TYPE_GPS, gpsRate);
        }

        return result;
    }

    /**
     * set watch gps period
     *
     * @param watchPeriodDto    watch period dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchGpsPeriod(WatchPeriodDto watchPeriodDto, LoginAuthDto loginAuthDto) {


        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchPeriodDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 3.校验时间段开始时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodStart() != null,
                cmnyMessageSource.getMessage("watch.config.period.start.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodStart()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 4.校验时间段结束时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodEnd() != null,
                cmnyMessageSource.getMessage("watch.config.period.end.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodEnd()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 5.更新手环配置
        dmcWatchConfUpt.setGpsPeriod(watchPeriodDto.getPeriodStart() + watchPeriodDto.getPeriodEnd());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);
        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环GPS静默时间段
            watchMessageHandler.setPeriod(deviceNo, WatchConstant.WATCH_CONF_PERIOD_GPS,
                    watchPeriodDto.getPeriodStart(), watchPeriodDto.getPeriodEnd());
        }

        return result;
    }

    /**
     * set watch power period
     *
     * @param watchPeriodDto    watch period dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchPowerPeriod(WatchPeriodDto watchPeriodDto,
                                       LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchPeriodDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 3.校验时间段开始时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodStart() != null,
                cmnyMessageSource.getMessage("watch.config.period.start.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodStart()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 4.校验时间段结束时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodEnd() != null,
                cmnyMessageSource.getMessage("watch.config.period.end.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodEnd()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 5.更新手环配置
        dmcWatchConfUpt.setPowerPeriod(watchPeriodDto.getPeriodStart() + watchPeriodDto.getPeriodEnd());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);
        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环低电量提醒时间段
            watchMessageHandler.setPeriod(deviceNo, WatchConstant.WATCH_CONF_PERIOD_POWER,
                    watchPeriodDto.getPeriodStart(), watchPeriodDto.getPeriodEnd());
        }

        return result;

    }

    /**
     * set watch power period
     *
     * @param watchPeriodDto watch period dto
     * @param loginAuthDto          login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchBalancePeriod(WatchPeriodDto watchPeriodDto,
                                         LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchPeriodDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 3.校验时间段开始时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodStart() != null,
                cmnyMessageSource.getMessage("watch.config.period.start.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodStart()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 4.校验时间段结束时间
        Preconditions.checkArgument(watchPeriodDto.getPeriodEnd() != null,
                cmnyMessageSource.getMessage("watch.config.period.end.empty", null));

        Preconditions.checkArgument(PubUtils.isPeriod(watchPeriodDto.getPeriodEnd()),
                cmnyMessageSource.getMessage("watch.config.period.pattern", null));

        // 5.更新手环配置
        dmcWatchConfUpt.setBalancePeriod(watchPeriodDto.getPeriodStart() + watchPeriodDto.getPeriodEnd());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发手环余额不足提醒时间段
            watchMessageHandler.setPeriod(deviceNo, WatchConstant.WATCH_CONF_PERIOD_BALANCE,
                    watchPeriodDto.getPeriodStart(), watchPeriodDto.getPeriodEnd());
        }

        return result;
    }

    /**
     * set watch time zone
     *
     * @param watchTimeZoneDto  watch time zone dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchTimeZone(WatchTimeZoneDto watchTimeZoneDto, LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchTimeZoneDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验时区是否合法
        Preconditions.checkArgument(watchTimeZoneDto.getTimeZone() != null,
                cmnyMessageSource.getMessage("watch.config.time.zone.empty", null));

        Preconditions.checkArgument(WatchTimeZoneEnum.getValue(watchTimeZoneDto.getTimeZone()) != null,
                cmnyMessageSource.getMessage("watch.config.time.zone.error", null));

        // 3.更新时区
        dmcWatchConfUpt.setTimeZone(watchTimeZoneDto.getTimeZone());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 4.下发时区
        if (result > 0) {
            watchMessageHandler.setTimeZone(deviceNo, watchTimeZoneDto.getTimeZone());
        }

        return result;
    }

    /**
     * set watch gps switch
     *
     * @param watchSwitchDto    watch switch dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchGpsSwitch(WatchSwitchDto watchSwitchDto, LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchSwitchDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验gps开关是否合法
        Preconditions.checkArgument(watchSwitchDto.getSwitchs() != null,
                cmnyMessageSource.getMessage("watch.config.switch.null", null));

        Preconditions.checkArgument(watchSwitchDto.getSwitchs() >= 0
                        && watchSwitchDto.getSwitchs() <= 1,
                cmnyMessageSource.getMessage("watch.config.switch.range", null));

        // 3.更新GPS开关
        dmcWatchConfUpt.setGpsSwitch(watchSwitchDto.getSwitchs());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 4.下发GPS开关
        if (result > 0) {
            watchMessageHandler.setLogicSwitch(deviceNo,
                    WatchConstant.WATCH_CONF_SWITCH_GPS, watchSwitchDto.getSwitchs());
        }

        return result;
    }

    /**
     * set watch white list switch
     *
     * @param watchSwitchDto    watch switch dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchWhiteListSwitch(WatchSwitchDto watchSwitchDto, LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchSwitchDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验白名单开关是否合法
        Preconditions.checkArgument(watchSwitchDto.getSwitchs() != null,
                cmnyMessageSource.getMessage("watch.config.switch.null", null));

        Preconditions.checkArgument(watchSwitchDto.getSwitchs() >= 0
                        && watchSwitchDto.getSwitchs() <= 1,
                cmnyMessageSource.getMessage("watch.config.switch.range", null));

        // 3.更新白名单开关
        dmcWatchConfUpt.setWhiteSwitch(watchSwitchDto.getSwitchs());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 5.下发白名单开关
        if (result > 0) {
            watchMessageHandler.setLogicSwitch(deviceNo,
                    WatchConstant.WATCH_CONF_SWITCH_WHITE, watchSwitchDto.getSwitchs());
        }

        return result;
    }

    /**
     * set watch yellow key sms switch
     *
     * @param watchSwitchDto    watch switch dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchYellowKeySmsSwitch(WatchSwitchDto watchSwitchDto, LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchSwitchDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验黄键短信开关是否合法
        Preconditions.checkArgument(watchSwitchDto.getSwitchs() != null,
                cmnyMessageSource.getMessage("watch.config.switch.null", null));

        Preconditions.checkArgument(watchSwitchDto.getSwitchs() >= 0
                        && watchSwitchDto.getSwitchs() <= 1,
                cmnyMessageSource.getMessage("watch.config.switch.range", null));

        // 3.更新黄键短信开关
        dmcWatchConfUpt.setYellowKeySwitch(watchSwitchDto.getSwitchs());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 4.下发黄键短信开关
        if (result > 0) {
            watchMessageHandler.setLogicSwitch(deviceNo,
                    WatchConstant.WATCH_CONF_SWITCH_YELLOW, watchSwitchDto.getSwitchs());
        }

        return result;
    }

    /**
     * set watch red key sms switch
     *
     * @param watchSwitchDto    watch switch dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchRedKeySmsSwitch(WatchSwitchDto watchSwitchDto, LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(watchSwitchDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验红键短信开关是否合法
        Preconditions.checkArgument(watchSwitchDto.getSwitchs() != null,
                cmnyMessageSource.getMessage("watch.config.switch.null", null));

        Preconditions.checkArgument(watchSwitchDto.getSwitchs() >= 0
                && watchSwitchDto.getSwitchs() <= 1,
                cmnyMessageSource.getMessage("watch.config.switch.range", null));

        // 3.更新红键短信开关
        dmcWatchConfUpt.setRedKeySwitch(watchSwitchDto.getSwitchs());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 4.下发红键短信开关
        if (result > 0) {
            watchMessageHandler.setLogicSwitch(deviceNo,
                    WatchConstant.WATCH_CONF_SWITCH_RED, watchSwitchDto.getSwitchs());
        }

        return result;
    }

    /**
     * set watch volume
     *
     * @param watchVolumeDto    watch volume dto
     * @param loginAuthDto      login auth dto
     *
     * @return the int
     */
    @Override
    public Integer setWatchVolume(WatchVolumeDto watchVolumeDto, LoginAuthDto loginAuthDto) {

        Long deviceId = watchVolumeDto.getDeviceId();
        Integer volume = watchVolumeDto.getVolume();

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(deviceId);
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        // 2.校验音量是否合法
        Preconditions.checkArgument(volume != null,
                cmnyMessageSource.getMessage("watch.config.volume.null", null));

        Preconditions.checkArgument(volume >= 1
                && volume <= 7,
                cmnyMessageSource.getMessage("watch.config.volume.range", null));

        // 3.更新音量
        dmcWatchConfUpt.setVolume(watchVolumeDto.getVolume());
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);

        // 4.下发音量
        if (result > 0) {
            watchMessageHandler.setVolume(deviceNo, volume);
        }

        return result;
    }

    /**
     * query watch white list by device id
     *
     * @param deviceId device id
     * @return the list by device id
     */
    @Override
    public List<String> queryWatchWhiteListByDeviceId(Long deviceId) {

        List<String> whiteList = new ArrayList<>();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(deviceId);

        String whiteListStr = dmcWatchConf.getWhiteList();
        if (PublicUtil.isNotEmpty(whiteListStr)) {
            whiteList = Arrays.asList(whiteListStr.split("&"));
        }

        return whiteList;
    }

    /**
     * add watch white list phone
     *
     * @param addWatchWhiteListDto  add watch white list dto
     * @param loginAuthDto          login auth dto
     *
     * @return the int
     */
    @Override
    public Integer addWatchWhiteListPhone(AddWatchWhiteListDto addWatchWhiteListDto,
                                          LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(addWatchWhiteListDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        Preconditions.checkArgument(addWatchWhiteListDto.getPhone() != null,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.empty", null));

        Preconditions.checkArgument(PubUtils.isMobileNumber(addWatchWhiteListDto.getPhone()),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.pattern", null));

        String whiteListStr = dmcWatchConf.getWhiteList();
        if (PubUtils.isNull(whiteListStr)) {
            whiteListStr = addWatchWhiteListDto.getPhone();
        } else {
            // 判断白名单是否已经存在
            if (whiteListStr.contains(addWatchWhiteListDto.getPhone())) {
                throw new DmcBizException(ErrorCodeEnum.DMC100610049);
            }
            whiteListStr = whiteListStr + "&" + addWatchWhiteListDto.getPhone();
        }

        dmcWatchConfUpt.setWhiteList(whiteListStr);
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发白名单列表
            watchMessageHandler.setWhiteList(deviceNo, whiteListStr);
        }

        return result;
    }

    /**
     * edit watch white list phone
     *
     * @param editWatchWhiteListDto edit watch white list dto
     * @param loginAuthDto          login auth dto
     *
     * @return the int
     */
    @Override
    public Integer editWatchWhiteListPhone(EditWatchWhiteListDto editWatchWhiteListDto,
                                           LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(editWatchWhiteListDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        Preconditions.checkArgument(editWatchWhiteListDto.getPhone() != null,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.empty", null));

        Preconditions.checkArgument(PubUtils.isMobileNumber(editWatchWhiteListDto.getPhone()),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.pattern", null));

        Preconditions.checkArgument(editWatchWhiteListDto.getNumber() != null,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.null", null));

        Preconditions.checkArgument(editWatchWhiteListDto.getNumber() >= 0,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.range", null));

        String whiteListStr = dmcWatchConf.getWhiteList();
        Preconditions.checkArgument(!PubUtils.isNull(whiteListStr),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.range", null));

        List<String> whiteList = Arrays.asList(whiteListStr.split("&"));

        Preconditions.checkArgument(whiteList != null && whiteList.size() >= 0
                        && editWatchWhiteListDto.getNumber() < whiteList.size(),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.error", null));

        whiteList.set(editWatchWhiteListDto.getNumber(), editWatchWhiteListDto.getPhone());
        Map<String, Long> countMap = whiteList.stream().collect(Collectors.groupingBy(w->w, Collectors.counting()));
        if (countMap.get(editWatchWhiteListDto.getPhone()).compareTo(1L) > 0) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610049);
        }

        whiteListStr = StringUtils.join(whiteList, "&");

        dmcWatchConfUpt.setWhiteList(whiteListStr);
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发白名单列表
            watchMessageHandler.setWhiteList(deviceNo, whiteListStr);
        }

        return result;
    }

    /**
     * delete watch white list phone
     *
     * @param deleteWatchWhiteListDto   delete watch white list dto
     * @param loginAuthDto              login auth dto
     *
     * @return the int
     */
    @Override
    public Integer deleteWatchWhiteListPhone(DeleteWatchWhiteListDto deleteWatchWhiteListDto,
                                             LoginAuthDto loginAuthDto) {

        DmcWatchConf dmcWatchConfUpt = new DmcWatchConf();

        // 1、校验设备Id && 校验设备Id是否存在配置项(是否绑定)
        DmcWatchConf dmcWatchConf =  queryDmcWatchConfigByDeviceId(deleteWatchWhiteListDto.getDeviceId());
        dmcWatchConfUpt.setId(dmcWatchConf.getId());

        Preconditions.checkArgument(deleteWatchWhiteListDto.getNumber() != null,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.null", null));

        Preconditions.checkArgument(deleteWatchWhiteListDto.getNumber() >= 0,
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.range", null));

        String whiteListStr = dmcWatchConf.getWhiteList();
        Preconditions.checkArgument(!PubUtils.isNull(whiteListStr),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.range", null));

        List<String> whiteList = new ArrayList<>(Arrays.asList(whiteListStr.split("&")));

        Preconditions.checkArgument(whiteList != null && whiteList.size() >= 0
                        && deleteWatchWhiteListDto.getNumber() < whiteList.size(),
                cmnyMessageSource.getMessage("watch.config.white.list.phone.number.error", null));

        int number = deleteWatchWhiteListDto.getNumber();
        whiteList.remove(number);
        if (PublicUtil.isNotEmpty(whiteList)) {
            whiteListStr = StringUtils.join(whiteList, "&");
        } else {
            whiteListStr = "";
        }

        dmcWatchConfUpt.setWhiteList(whiteListStr);
        dmcWatchConfUpt.setUpdateInfo(loginAuthDto);

        Integer result = watchConfDao.updateByPrimaryKeySelective(dmcWatchConfUpt);
        if (result > 0) {
            // 下发白名单列表
            watchMessageHandler.setWhiteList(deviceNo, whiteListStr);
        }

        return result;
    }

    /**
     * init dmc watch config
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer initDmcWatchConfig(Long deviceId) {

        DmcWatchConf dmcWatchConf = new DmcWatchConf();
        dmcWatchConf.setId(deviceId);

        Integer result = watchConfDao.insertSelective(dmcWatchConf);

        return result;
    }

    /**
     * remove dmc watch config
     *
     * @param deviceId device id
     * @return the int
     */
    @Override
    public Integer removeDmcWatchConfig(Long deviceId) {

        Integer result = watchConfDao.deleteByPrimaryKey(deviceId);

        return result;
    }
}
